﻿using System;
using System.Collections.Generic;


namespace Sencha.Serialization.Contracts
{
	internal static class CollectionExtentions
	{	
		public static bool Contains(this ICollection<MemberDescription> @this, string memberName)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (memberName == null)
				throw new ArgumentNullException("memberName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();


			return Contains(@this, memberName, true);
		}
		public static bool Contains(this ICollection<MemberDescription> @this, string memberName, bool caseSensitive = true)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (memberName == null)
				throw new ArgumentNullException("memberName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			var comparison = caseSensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;

			foreach (var member in @this)
			{
				if (string.Equals(member.Name, memberName, comparison))
					return true;
			}

			return false;
		}

		public static MemberDescription Find(this ICollection<MemberDescription> @this, string memberName)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (memberName == null)
				throw new ArgumentNullException ("memberName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();


			return Find(@this, memberName, true);
		}
		public static MemberDescription Find(this ICollection<MemberDescription> @this, string memberName, bool caseSensitive = true)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (memberName == null)
				throw new ArgumentNullException("memberName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			var comparison = caseSensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;

			foreach (var member in @this)
			{
				if (string.Equals(member.Name, memberName, comparison))
					return member;
			}

			return null;
		}

		public static IEnumerable<MemberDescription> FindAll(this ICollection<MemberDescription> @this, string memberName)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (memberName == null)
				throw new ArgumentNullException("memberName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();


			return FindAll(@this, memberName);
		}
		public static IEnumerable<MemberDescription> FindAll(this ICollection<MemberDescription> @this, string memberName, bool caseSensitive = true)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (memberName == null)
				throw new ArgumentNullException("memberName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			var comparison = caseSensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;

			foreach (var member in @this)
			{
				if (string.Equals(member.Name, memberName, comparison))
					yield return member;
			}
		}

		public static bool Contains(this ICollection<TypeDescription> @this, string typeName)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (typeName == null)
				throw new ArgumentNullException("typeName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			return Contains(@this, typeName, true);
		}
		public static bool Contains(this ICollection<TypeDescription> @this, string typeName, bool caseSensitive = true)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (typeName == null)
				throw new ArgumentNullException("typeName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			var comparison = caseSensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;

			foreach (var member in @this)
			{
				if (string.Equals(member.Name, typeName, comparison) || string.Equals(member.TypeFullName, typeName, comparison))
					return true;
			}

			return false;
		}

		public static TypeDescription Find(this ICollection<TypeDescription> @this, string typeName)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (typeName == null)
				throw new ArgumentNullException("typeName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			return Find(@this, typeName, true);
		}
		public static TypeDescription Find(this ICollection<TypeDescription> @this, string typeName, bool caseSensitive = true)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (typeName == null)
				throw new ArgumentNullException("typeName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			var comparison = caseSensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;

			foreach (var member in @this)
			{
				if (string.Equals(member.Name, typeName, comparison) || string.Equals(member.TypeFullName, typeName, comparison))
					return member;
			}

			return null;
		}

		public static IEnumerable<TypeDescription> FindAll(this ICollection<TypeDescription> @this, string typeName)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (typeName == null)
				throw new ArgumentNullException("typeName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			return FindAll(@this, typeName);
		}
		public static IEnumerable<TypeDescription> FindAll(this ICollection<TypeDescription> @this, string typeName, bool caseSensitive = true)
		{
			if (@this == null)
				throw new NullReferenceException();
			if (typeName == null)
				throw new ArgumentNullException("typeName");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			var comparison = caseSensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;

			foreach (var member in @this)
			{
				if (string.Equals(member.Name, typeName, comparison) || string.Equals(member.TypeFullName, typeName, comparison))
					yield return member;
			}
		}

	}
}
